'''
Created on Dec 13, 2010

@author: mkiyer
'''
import logging
#import argparse
import os
import sys

from optparse import OptionParser
from job_runner import qsub_cac, qsub_loc, run_local
from config import ExomePipelineConfig, ExomeAnalysisConfig
import run_lane
from bam_cleaner import bam_cleaner_samples
import exome.gatk_cluster.reads_realignment_job as rra
import exome.snps_callers.snps_byGatk_byPatient as gtk
import exome.snps_callers.snps_bySamTools_byPatient as sst


def run_analysis(analysis_file, config_file, num_processors, runfunc):
    #
    # Read configuration
    #
    config = ExomePipelineConfig()
    config.from_xml(config_file)
    analysis = ExomeAnalysisConfig()
    analysis.from_xml(analysis_file, config.output_dir)
    
    for run_name, run in config.run_param.iteritems():
        # Run parameters        
        do_recalibration, quick_dirty, do_paired_samples, multi_samples, analysis_type = \
        run.do_recal, run.quick_dirty, run.paired_samples, run.multi_samples, run.analysis_type

        # Main loop for all samples
        lane_deps = []
        for sample in analysis.samples:
            # Create sample directory
            if not os.path.exists(sample.output_dir):
                logging.info("Created sample dir %s" % (sample.output_dir))
                os.makedirs(sample.output_dir)
            #
            # Process lanes
            #
            #lane_deps = []
            for lane in sample.lanes:
                logging.info("Processing lane %s" % (lane.name))
                # write lane configuration to a separate XML file
                xmlstring = lane.to_xml()
                lane_file = os.path.join(sample.output_dir, lane.name + ".xml")
                f = open(lane_file, "w")
                print >>f, xmlstring
                f.close()
                # run lane job
                thlane_deps=run_lane.run_job(lane_file, analysis.lane_dir, config_file, num_processors, runfunc)
                lane_deps.extend(thlane_deps)
                print lane_deps     
                #pass
        
        #sys.exit(0)
        # Start 
        # Processing Step 
        # Call Variants Step
        recal_deps, gtk_deps, sst_deps=[],[],[]
        no_recal_deps=[]
            
        if do_recalibration and quick_dirty: 
            
            use_recal_files=False
            
            recal_deps.extend(rra.fast_lane_level_processing(analysis, config, num_processors, runfunc, lane_deps,config_file))
            no_recal_deps.extend( bam_cleaner_samples(analysis, config, num_processors, runfunc, lane_deps) )
            
            if do_paired_samples:
                gtk_deps.extend(gtk.snps_calling_pairedSamples(analysis, config, num_processors, runfunc, recal_deps))
                #sst_deps.extend(sst.snps_calling_pairedSamples(analysis, config, do_recalibration, runfunc, recal_deps))
                sst_deps.extend(sst.snps_calling_pairedSamples(analysis, config, use_recal_files, runfunc, no_recal_deps))
                
                
            elif multi_samples:
                # 24-1-11: Need to finish those functions
                gtk_deps.extend(gtk.snps_calling_multipleSamples(analysis, config, num_processors, runfunc, recal_deps))
                #sst_deps.extend(sst.snps_calling_multipleSamples(analysis, config, do_recalibration, runfunc, recal_deps))
                sst_deps.extend(sst.snps_calling_multipleSamples(analysis, config, use_recal_files, runfunc, no_recal_deps))


        elif do_recalibration and not quick_dirty:
            recal_deps.extend(rra.fast_lane_level_processing(analysis, config, num_processors, runfunc, lane_deps,config_file))
            if do_paired_samples:
                gtk_deps.extend(gtk.snps_calling_pairedSamples(analysis, config, num_processors, runfunc, recal_deps))
                sst_deps.extend(sst.snps_calling_pairedSamples(analysis, config, do_recalibration, runfunc, recal_deps))
                
            elif multi_samples:
                # 24-1-11: Need to finish those functions
                gtk_deps.extend(gtk.snps_calling_multipleSamples(analysis, config, num_processors, runfunc, recal_deps))
                sst_deps.extend(sst.snps_calling_multipleSamples(analysis, config, do_recalibration, runfunc, recal_deps))
                      
        elif quick_dirty and not  do_recalibration:
            
            use_recal_files=False
            no_recal_deps.extend( bam_cleaner_samples(analysis, config, num_processors, runfunc, lane_deps) )
            ###### Modify here to use the BAM files not with out recalibration        
            if do_paired_samples:
                sst_deps.extend(sst.snps_calling_pairedSamples(analysis, config, use_recal_files, runfunc, no_recal_deps))
            elif multi_samples:
                sst_deps.extend(sst.snps_calling_multipleSamples(analysis, config, use_recal_files, runfunc, no_recal_deps))

        pass



def main():
    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    """
    NOTE 12-27-2010: parser was changed by optionparser because the first is not a 
    standard package of python. 
    parser = argparse.ArgumentParser()
    parser.add_argument("--local", dest="local", action="store_true", default=False)
    parser.add_argument("--cluster", dest="cluster", action="store_true", default=False)
    parser.add_argument("-p", "--processes", type=int, dest="num_processors", default=1)
    parser.add_argument("analysis_file")
    parser.add_argument("config_file")
    options = parser.parse_args()
    """
    optionparser = OptionParser("usage: %prog [options] ")
    
    optionparser.add_option("-r", "--config_file", dest="config_file",
                            help="file with run configuration")
    optionparser.add_option("-a", "--analysis_file", dest="analysis_file",
                            help="file with experiment configuration") 
    optionparser.add_option("--quality_recal", dest="quality_recal", action="store_true", default=False,
                            help="Performs base quality recalibration") 
    optionparser.add_option("--paired_samples", dest="paired_samples", action="store_true", default=False,
                            help="paired samples snv calling, default multisamples") 
    '''
    optionparser.add_option("--multi_samples", dest="multi_samples", action="store_true", default=False,
                            help="multi-sample snv calling, default paired samples")  
    '''
    optionparser.add_option("--local", dest="local", action="store_true", default=False)
    optionparser.add_option("--cluster", dest="cluster", action="store_true", default=False)
    optionparser.add_option("--local_cluster", dest="local_cluster", action="store_true", default=False)
    
    optionparser.add_option("-p", "--processes", type=int, dest="num_processors", default=1)
    
    
    (options, args) = optionparser.parse_args()
    
    #analysis_file, config_file = args[0], args[1]
     
        
    if not (options.local ^ options.cluster ^ options.local_cluster):
        optionparser.error("Must set either --local, --cluster or --local_cluster to run job")
    if options.local:
        jobrunfunc = run_local
    elif options.cluster:
        jobrunfunc = qsub_cac
    elif options.local_cluster:
        jobrunfunc = qsub_loc
        
    #run_analysis(options.analysis_file, options.config_file, options.num_processors, jobrunfunc)
    run_analysis(options.analysis_file, options.config_file, options.num_processors, jobrunfunc)

if __name__ == '__main__': main()